#include "pthread.hpp"
#include <iostream>
#include <vector>
#include <string>
#include "Mutex.hpp"

// #define NUM 4
// int tickets = 10000;

// class ThreadData
// {
// public:
//     std::string _name;
//     pthread_mutex_t *_lock_ptr;
// };

// void ticket(ThreadData &td)
// {
//     while (true)
//     {
//         pthread_mutex_lock(td._lock_ptr);
//         if (tickets > 0)
//         {
//             usleep(1000);
//             std::cout << td._name.c_str() << ": " << std::to_string(tickets--) << std::endl;
//             usleep(100);
//         }
//         else
//         {
//             pthread_mutex_unlock(td._lock_ptr);
//             break;
//         }
//         pthread_mutex_unlock(td._lock_ptr);
//     }
// }

// int main()
// {
//     std::vector<My_Thread::Thread<ThreadData>> threas; // 这里使用了自己封装的thread
//     pthread_mutex_t lock;
//     pthread_mutex_init(&lock, nullptr);
//     for (int i = 0; i < NUM; i++)
//     {
//         ThreadData *td = new ThreadData;
//         td->_lock_ptr = &lock;
//         threas.emplace_back(ticket, *td);
//         td->_name = threas.back().Name();
//     }

//     for (auto &t : threas)
//     {
//         t.Start();
//     }

//     for (auto &t : threas)
//     {
//         t.Jion();
//     }

//     pthread_mutex_destroy(&lock);
//     return 0;
// }

#define NUM 4
int tickets = 10000;

class ThreadData
{
public:
    std::string _name;
    My_Mutex::Mutex *_lock_ptr;
};

void ticket(ThreadData &td)
{
    while (true)
    {
        My_Mutex::LockGuard lg;
        if (tickets > 0)
        {
            usleep(1000);
            std::cout << td._name.c_str() << ": " << std::to_string(tickets--) << std::endl;
            usleep(1000);
        }
        
       
    }
}

int main()
{
    std::vector<My_Thread::Thread<ThreadData>> threas; // 这里使用了自己封装的thread
    My_Mutex::Mutex lock;
    for (int i = 0; i < NUM; i++)
    {
        ThreadData *td = new ThreadData;
        td->_lock_ptr = &lock;
        threas.emplace_back(ticket, *td);
        td->_name = threas.back().Name();
    }

    for (auto &t : threas)
    {
        t.Start();
    }

    for (auto &t : threas)
    {
        t.Jion();
    }

    return 0;
}
